/**
 * 
 */
package nl.project.dataImport;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

/**
 * @author Zerocool
 * 
 */
public class TestImport extends HttpServlet {

	private FileReader theachers;
	private FileReader parents;
	private FileReader students;
	private FileReader combo;
	private FileReader employees;
	private FileReader courses;
	private FileReader cord;
	public TestImport() {

		try {

			theachers = new FileReader("input_data/DKC_docenten_final_2.txt");
			parents = new FileReader("input_data/DKC_voogdouder_final_2.txt");
			students = new FileReader("input_data/DKC_leerlingen_final.txt");
			employees = new FileReader("input_data/DKC_medewerkers_final.txt");
			combo = new FileReader("input_data/DKC_KVDcombinaties_final.txt");
			courses = new FileReader("input_data/DKC_vakken_final.txt");
			cord = new FileReader("input_data/coordinates.txt");
			 
		} catch (FileNotFoundException e) {

		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * this wil put files declared in de conscrutor to be CONVERT() and put in
	 * appropriate entity's en put them in the datastore
	 * 
	 * @see
	 * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
	 * , javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		ArrayList<ArrayList<String>> theachersTable = tableIt(this.theachers,
				req, resp);
		ArrayList<ArrayList<String>> studentsTable = tableIt(this.students,
				req, resp);
		ArrayList<ArrayList<String>> parentsTable = tableIt(this.parents, req,
				resp);
		ArrayList<ArrayList<String>> employeesTable = tableIt(this.employees,
				req, resp);
		ArrayList<ArrayList<String>> comboTable = tableIt(this.combo, req, resp);
		ArrayList<ArrayList<String>> coursesTable = tableIt(this.courses, req,
				resp);
		ArrayList<ArrayList<String>> cordTable = tableIt(this.cord, req,
				resp);

		DatastoreService datastore = DatastoreServiceFactory
				.getDatastoreService();
		Key parentKey = KeyFactory.createKey("Parents", "Parents");

		for (int i = 0; i < parentsTable.size(); i++) {

			Entity parents = new Entity("Parent", parentKey);
			parents.setProperty("parentId", parentsTable.get(i).get(0));

			String password = "password" + i;
			parents.setProperty("password", password);

			parents.setProperty("title", parentsTable.get(i).get(1));
			parents.setProperty("initials", parentsTable.get(i).get(2));
			parents.setProperty("prefixes", parentsTable.get(i).get(3));
			parents.setProperty("surName", parentsTable.get(i).get(4));
			parents.setProperty("rol", parentsTable.get(i).get(5));
			parents.setProperty("addressLine", parentsTable.get(i).get(6));
			parents.setProperty("addressNumber", parentsTable.get(i).get(7));
			parents.setProperty("residence", parentsTable.get(i).get(8));
			parents.setProperty("zipCode", parentsTable.get(i).get(9));
			parents.setProperty("cellPhoneNumber", parentsTable.get(i).get(10));
			parents.setProperty("homeNumber", parentsTable.get(i).get(11));
			parents.setProperty("emailAddress", parentsTable.get(i).get(12));
			parents.setProperty("lat", cordTable.get(i).get(0));
			parents.setProperty("long", cordTable.get(i).get(1));

			
			ArrayList<String> studentIDs = new ArrayList<String>();

			for (int j = 0; j < studentsTable.size(); j++) {

				if (parentsTable.get(i).get(0)
						.compareToIgnoreCase(studentsTable.get(j).get(6)) == 0) {

					studentIDs.add(studentsTable.get(j).get(0));
				}
			}

			parents.setProperty("studentIDs", studentIDs);
			datastore.put(parents);

		}

		Key studentsKey = KeyFactory.createKey("Students", "Students");

		for (int i = 0; i < studentsTable.size(); i++) {
			Entity students = new Entity("Student", studentsKey);
			students.setProperty("studentId", studentsTable.get(i).get(0));
			students.setProperty("firstName", studentsTable.get(i).get(1));
			students.setProperty("preposition", studentsTable.get(i).get(2));
			students.setProperty("surName", studentsTable.get(i).get(3));
			students.setProperty("sex", studentsTable.get(i).get(4));
			students.setProperty("classCode", studentsTable.get(i).get(5));
			students.setProperty("parentId", studentsTable.get(i).get(6));
			datastore.put(students);

			for (int k = 0; k < comboTable.size(); k++) {
				//System.out.println("k= " + k);
				if (comboTable.get(k).get(0)
						.compareToIgnoreCase(studentsTable.get(i).get(5)) == 0) {

					//System.out.println("gevonden bij k = " + k + " "		+ comboTable.get(k).get(0) + " "					+ studentsTable.get(i).get(5));
					//System.out.println(comboTable.get(k).get(0));
					//System.out.println(comboTable.get(k).get(1));
					//System.out.println(comboTable.get(k).get(2));

					Entity vak = new Entity("vak", students.getKey());
					vak.setProperty("classCode", comboTable.get(k).get(0));
					vak.setProperty("courseCode", comboTable.get(k).get(1));
					vak.setProperty("theacherCode", comboTable.get(k).get(2));

					for (int l = 0; l < theachersTable.size(); l++) {
						//System.out.println("l= " + l);

						if (comboTable
								.get(k)
								.get(2)
								.compareToIgnoreCase(
										theachersTable.get(l).get(0)) == 0) {

							//System.out.println("gevonden bij l = " + l + " "					+ comboTable.get(k).get(2) + " "									+ theachersTable.get(l).get(0));
							//System.out.println(theachersTable.get(l).get(1));
							//System.out.println(theachersTable.get(l).get(2));
							//System.out.println(theachersTable.get(l).get(3));

							vak.setProperty("theacherName",
									theachersTable.get(l).get(1));
							vak.setProperty("theacherMailBoxNumber",
									theachersTable.get(l).get(2));
							vak.setProperty("theacherEmail", theachersTable
									.get(l).get(3));
							vak.setProperty("theacherID", l);

							break;
						}
					}

					for (int l = 0; l < coursesTable.size(); l++) {
						//System.out.println("l= " + l);
						if (comboTable
								.get(k)
								.get(1)
								.compareToIgnoreCase(coursesTable.get(l).get(0)) == 0) {

							//System.out.println("gevonden bij l = " + l + " "						+ comboTable.get(k).get(1) + " "									+ coursesTable.get(l).get(0));
							//System.out.println(coursesTable.get(l).get(1));

							vak.setProperty("courseName", coursesTable.get(l)
									.get(1));
							break;
						}

					}
					try {
						datastore.put(vak);
						//System.out			.println("entty vak geplaats voor student  = "		+ students.getKey());
					} catch (Exception e) {
						//System.out								.println("entty vak niet geplaats voor student  = "	+ students.getKey());
						e.printStackTrace();
					}
				}
			}

			/*
			 * ArrayList<ArrayList<String>> kvdPerKlas = new
			 * ArrayList<ArrayList<String>>();
			 * 
			 * for (int j = 0; j < comboTable.size(); j++) {
			 * 
			 * if (comboTable.get(j).get(0) == studentsTable.get(i).get(5)) {
			 * 
			 * vak.setProperty("classCode", comboTable.get(j).get(0));
			 * vak.setProperty("courseCode", comboTable.get(j).get(1));
			 * vak.setProperty("theacherCode", comboTable.get(j).get(2));
			 * 
			 * // kvdPerKlas.add(comboTable.get(j));
			 * 
			 * } }
			 * 
			 * for (int j = 0; j < kvdPerKlas.size(); j++) { if
			 * (kvdPerKlas.get(j).get(2) == theachersTable.get(j).get(0)) {
			 * 
			 * vak.setProperty("theacherName", theachersTable.get(j) .get(1));
			 * vak.setProperty("theacherMailBoxNumber", theachersTable
			 * .get(j).get(2)); vak.setProperty("theacherEmail",
			 * theachersTable.get(j).get(3));
			 * 
			 * // kvdPerKlas.get(j).add(theachersTable.get(j).get(1)); //
			 * kvdPerKlas.get(j).add(theachersTable.get(j).get(2)); //
			 * kvdPerKlas.get(j).add(theachersTable.get(j).get(3));
			 * 
			 * } } for (int j = 0; j < kvdPerKlas.size(); j++) {
			 * 
			 * if (kvdPerKlas.get(j).get(1) == coursesTable.get(j).get(0)) {
			 * 
			 * vak.setProperty("courseName", coursesTable.get(j).get(1));
			 * 
			 * // kvdPerKlas.get(j).add(coursesTable.get(j).get(1)); }
			 * 
			 * }
			 * 
			 * // students.setProperty("class",kvdPerKlas);
			 */

		}

		// testDatastore(req, resp);

		fabricateEnrollments();
		fabricateStudentResults();
		//MakeThreeEnrollements();

	}

	/**
	 * 1 docent, zelfde dag, zelfde pref, 3 afspraken zelfde klas
	 * 
	 * voor testing purposuse only
	 */
	public void MakeThreeEnrollements() {

		oneEnrollment("2402");
		oneEnrollment("3112");
		oneEnrollment("2338");
	}

	public void oneEnrollment(String str) {
		DatastoreService d = DatastoreServiceFactory.getDatastoreService();
		Key Skey = KeyFactory.createKey("Students", "Students");

		Query Sq = new Query("Student", Skey).addFilter("studentId",
				FilterOperator.EQUAL, (String.valueOf(str)));
		List<Entity> Sl = d.prepare(Sq).asList(
				FetchOptions.Builder.withDefaults());

		for (int i = 0; i < (1); i++) {

			//System.out.println(Sl.get(i).toString());

			Key Pkey = KeyFactory.createKey("Parents", "Parents");
			Query Pq = new Query("Parent", Pkey).addFilter("parentId",
					FilterOperator.EQUAL,
					(String.valueOf(Sl.get(i).getProperty("parentId"))));
			Entity P = d.prepare(Pq).asSingleEntity();

			Query vQ = new Query("vak", Sl.get(i).getKey()).addFilter(
					"theacherCode", FilterOperator.EQUAL,
					String.valueOf("BAARR"));
			List<Entity> Vl = d.prepare(vQ).asList(
					FetchOptions.Builder.withDefaults());

			for (int j = 0; j < 1; j++) {
				Entity e = new Entity("Enrollment", P.getKey());
				e.setProperty("parentID", Sl.get(i).getProperty("parentId"));
				e.setProperty("theacherCode",
						Vl.get(j).getProperty("theacherCode"));
				e.setProperty("studentID", Sl.get(i).getProperty("studentId"));

				Query tQ = new Query("vak").addFilter("theacherCode",
						FilterOperator.EQUAL,
						Vl.get(j).getProperty("theacherCode"));
				List<Entity> tl = d.prepare(tQ).asList(
						FetchOptions.Builder.withDefaults());
				e.setProperty("theacherID", tl.get(0).getProperty("theacherID"));

				ArrayList<Boolean> s = new ArrayList<Boolean>();

				e.setProperty("pref", "Early");
				s.add(true);
				s.add(false);
				s.add(false);

				e.setProperty("days", s);

				ArrayList<String> c = new ArrayList<String>();
				c.add((String) P.getProperty("emailAddress"));
				c.add((String) P.getProperty("addressLine")
						+ (String) P.getProperty("addressNumber"));
				c.add((String) P.getProperty("zipCode"));
				c.add((String) P.getProperty("residence"));
				c.add((String) P.getProperty("cellPhoneNumber"));

				e.setProperty("contact", c);

				//System.out.println(e.toString());

				d.put(e);

			}
		}
	}

	/**
	 * Enrollment stress test This will take every student in de database,
	 * select 3 of its theachers and put een enrollment entity in de datastore
	 * 
	 * Prefrence (Pref) has semi-random value days (days) has semi random-value
	 * 
	 * for testing purposuse only shuld be removed on deployment
	 */
	public void fabricateEnrollments() {
		DatastoreService d = DatastoreServiceFactory.getDatastoreService();
		Key Skey = KeyFactory.createKey("Students", "Students");

		Query Sq = new Query("Student", Skey);
		List<Entity> Sl = d.prepare(Sq).asList(
				FetchOptions.Builder.withDefaults());

		for (int i = 0; i < (Sl.size() / 10); i++) {
			Key Pkey = KeyFactory.createKey("Parents", "Parents");
			Query Pq = new Query("Parent", Pkey).addFilter("parentId",
					FilterOperator.EQUAL,
					(String.valueOf(Sl.get(i).getProperty("parentId"))));
			Entity P = d.prepare(Pq).asSingleEntity();

			Query vQ = new Query("vak", Sl.get(i).getKey());
			List<Entity> Vl = d.prepare(vQ).asList(
					FetchOptions.Builder.withDefaults());

			for (int j = 0; j < 3; j++) {
				Entity e = new Entity("Enrollment", P.getKey());
				e.setProperty("parentID", Sl.get(i).getProperty("parentId"));
				e.setProperty("theacherCode",
						Vl.get(j).getProperty("theacherCode"));
				e.setProperty("studentID", Sl.get(i).getProperty("studentId"));

				Query tQ = new Query("vak").addFilter("theacherCode",
						FilterOperator.EQUAL,
						Vl.get(j).getProperty("theacherCode"));
				List<Entity> tl = d.prepare(tQ).asList(
						FetchOptions.Builder.withDefaults());
				e.setProperty("theacherID", tl.get(0).getProperty("theacherID"));

				ArrayList<Boolean> s = new ArrayList<Boolean>();
				if (j == 0) {
					e.setProperty("pref", "Early");
					s.add(true);
					s.add(true);
					s.add(true);
				}
				if (j == 1) {
					e.setProperty("pref", "Later");
					s.add(true);
					s.add(false);
					s.add(true);
				}
				if (j == 2) {
					e.setProperty("pref", "None");
					s.add(true);
					s.add(true);
					s.add(false);
				}
				e.setProperty("days", s);

				ArrayList<String> c = new ArrayList<String>();
				c.add((String) P.getProperty("emailAddress"));
				c.add((String) P.getProperty("addressLine")
						+ (String) P.getProperty("addressNumber"));
				c.add((String) P.getProperty("zipCode"));
				c.add((String) P.getProperty("residence"));
				c.add((String) P.getProperty("cellPhoneNumber"));

				e.setProperty("contact", c);

				d.put(e);
			}
		}

	}

	/**
	 * This wil fabriacate resluts between 1-10 for each course of every student
	 * 
	 * student 1->N course 1->N Grade
	 * 
	 * Grade = { decimal Grade, Date Date // YYYY-MM-DD float Weight , //gewicht
	 * van de cijfer string WeightName, // so rep test exam }
	 * 
	 * 
	 */
	public void fabricateStudentResults() {
		DatastoreService d = DatastoreServiceFactory.getDatastoreService();

		Key Skey = KeyFactory.createKey("Students", "Students");

		Query Sq = new Query("Student", Skey);
		List<Entity> Sl = d.prepare(Sq).asList(
				FetchOptions.Builder.withDefaults());

		// haal die /100 weg
		for (int i = 0; i < Sl.size()  ; i++) {

			Query Cq = new Query("vak", Sl.get(i).getKey());
			List<Entity> Cl = d.prepare(Cq).asList(
					FetchOptions.Builder.withDefaults());

			Random generator = new Random();
			for (int j = 0; j < Cl.size(); j++) {
				
				for (int k = 0; k < 5; k++) {
					
					Entity r = new Entity("Result", Cl.get(j).getKey());
					r.setProperty("courseCode", Cl.get(j).getProperty("courseCode"));
					r.setProperty("Grade", generator.nextInt(11) + 1);
					r.setProperty("Date", "2011-05-22");
					r.setProperty("Weight", generator.nextInt(6) + 1);
					r.setProperty("WeightName", "so");
					
					System.out.println("R: " + r.toString());
					
					d.put(r);
				}
			}
		}

	}

	public void testDatastore(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {

		DatastoreService datastore = DatastoreServiceFactory
				.getDatastoreService();
		// datastore.get();

		Key key = KeyFactory.createKey("Parents", "Parents");

		PrintWriter p = resp.getWriter();

		try {
			p.println("<h1>begin</h1>");

			// dit kan niet omdat de sleutel meedere entity terug geeft
			Entity t = datastore.get(key);
			p.println(t.getProperty("parentId"));
			p.println(t.getProperty("surName"));

			ArrayList<String> st = (ArrayList<String>) t.getProperty("studentIDs");

			for (int j = 0; j < st.size(); j++) {
				p.println(st.get(j));
			}

			p.flush();
		} catch (EntityNotFoundException e) {
			// TODO Auto-generated catch block
			//System.out.println("  niet gevonden");
			e.printStackTrace();
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest
	 * , javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}

	/**
	 * This reads a FileReader that has to point to a actual file in war
	 * direrctory. the file has to be a ';' delimeted file with no headers en no
	 * end token
	 * 
	 * 
	 * @param fr
	 *            FileReader
	 * @return double arraylist in a table format
	 */
	public ArrayList<ArrayList<String>> convert(FileReader fr) {

		ArrayList<ArrayList<String>> rows = new ArrayList<ArrayList<String>>();

		try {

			BufferedReader bufRead = new BufferedReader(fr);

			String line; // String that holds current file line
			int linecount = 0; // Line number of count

			// Read first line
			line = bufRead.readLine();

			linecount++;

			rows = new ArrayList<ArrayList<String>>();

			while (line != null) {
				StringBuilder a = new StringBuilder();
				a.append(line);
				a.append(";");
				line = a.toString();

				int colcount = 0; // col number of count
				ArrayList<String> col = new ArrayList<String>(); // for every
																	// column in
																	// the line
				StringBuilder sb = new StringBuilder();
				;

				// files must end with a ';', that the comma delimiter
				for (int i = 0; i < line.length(); i++) {

					if (line.charAt(i) == ';') {
						// new line, making new new columns
						col.add(sb.toString().trim());
						sb = new StringBuilder();
						colcount++;
						continue;

					}

					sb.append(line.charAt(i));

				}
				rows.add(col);
				line = bufRead.readLine();

			}

			/*
			 * // Read through file one line at time. Print line # and line
			 * while (line != null) { PrintWriter p = resp.getWriter();
			 * p.println(count + ": " + line); line = bufRead.readLine();
			 * count++; }
			 * 
			 * bufRead.close();
			 */
		} catch (ArrayIndexOutOfBoundsException exe) {

			/*
			 * If no file was passed on the command line, this expception is
			 * generated. A message indicating how to the class should be called
			 * is displayed
			 */
			// System.out.println("Usage: java ReadFile filename\n");

		} catch (IOException ex) {
			// If another exception is generated, print a stack trace
			// ex.printStackTrace();
		}

		return rows;

	}

	/**
	 * 
	 * this wil take a converted ArrayList<ArrayList<String>> and table it to
	 * html and foward the response back to the user, after taking it through
	 * the CONVER() method
	 * 
	 * @param fr
	 * @param req
	 * @param resp
	 * @return ArrayList<ArrayList<String>> from the CONVERT()
	 * @throws IOException
	 */
	public ArrayList<ArrayList<String>> tableIt(FileReader fr,
			HttpServletRequest req, HttpServletResponse resp)
			throws IOException {

		ArrayList<ArrayList<String>> rows = convert(fr);

		PrintWriter p = resp.getWriter();
		p.println("<table border='1'>");
		for (int i = 0; i < rows.size(); i++) {
			p.println("<tr>");
			ArrayList<String> col = rows.get(i);
			for (int j = 0; j < col.size(); j++) {

				p.println("<td>");
				p.println(col.get(j));
				p.println("</td>");

			}
			p.println("</tr>");

		}
		p.println("</table>");

		return rows;
	}

}
